package com.itheima.service;


import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.SetmealService;

import com.itheima.contant.SetmealRedisConstant;
import com.itheima.dao.OrderDao;
import com.itheima.dao.SetmealDao;
import com.itheima.entity.PageResult;
import com.itheima.entity.Result;
import com.itheima.pojo.CheckGroup;
import com.itheima.pojo.CheckItem;
import com.itheima.pojo.NameValueVCS;
import com.itheima.pojo.Setmeal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import redis.clients.jedis.JedisPool;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service(interfaceClass = SetmealService.class)
@Transactional
public class SetmealServiceImpl implements SetmealService {
    @Autowired
    private SetmealDao setmealDao;

    @Autowired
    private OrderDao orderDao;
    @Autowired
    JedisPool jedisPool;

    /*分页查询*/
    @Override
    public PageResult pageQuery(Integer currentPage, Integer pageSize, String queryString) {
        Page page = PageHelper.startPage(currentPage, pageSize);
        List<Setmeal> setmealList = setmealDao.pageQuery(queryString);
        return new PageResult(page.getTotal(), setmealList);
    }

    @Override
    public List<Setmeal> queryAll() {
        return setmealDao.queryAll();
    }

    /*添加套餐*/
    @Override
    public void addSetmeal(Setmeal setmeal) {
        //1、先添加套餐
        setmealDao.addSetmeal(setmeal);

        //2、添加关联

        //获取套餐id
        Integer setmealId = setmeal.getId();

        //获取检查组id集合
        List<Integer> checkgroupIds = setmeal.getCheckgroupIds();

        //封装套餐与检查组关联的集合
        List<Map> mapList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(checkgroupIds)) {
            for (Integer checkgroupId : checkgroupIds) {
                Map map = new HashMap();
                map.put("setmealId", setmealId);
                map.put("checkgroupId", checkgroupId);
                mapList.add(map);
            }
            setmealDao.addSetmealIdAndCheckgroupId(mapList);
        }

    }



    /*与数据库多次连接，比较耗时
        查询套餐信息，套餐信息中又包含检查组信息，检查组信息中又包含检查项信息*/
    @Override
    public Setmeal findById(Integer id) {
        /*
         * 思路：
         *  查询：
         *   1、先根据前台传过来的套餐id查询套餐信息
         *   2、再根据套餐id查询套餐包含的检查组（这里构造了一个检查组List）
         *   3、遍历检查组，根据检查组id查询检查组包含的检查项集合
         *
         *  封装：
         *   1、将检查项集合封装进检查组类对象的检查组字段中
         *   2、将检查组集合封装进套餐类对象的检查组字段中
         *
         * */

        /*根据套餐id，查询套餐信息*/
        Setmeal setmeal = setmealDao.querySetmealId(id);
        /*根据套餐id,查询检查组列表*/
        List<CheckGroup> checkGroupList = setmealDao.queryCheckGroup(setmeal.getId());

        if (CollectionUtils.isNotEmpty(checkGroupList)) {
            /*遍历检查组列表*/
            for (CheckGroup checkGroup : checkGroupList) {
                /*根据检查组id查询检查项集合*/
                List<CheckItem> checkItemList = setmealDao.queryCheckItem(checkGroup.getId());
                /*将此检查项集合装入该检查组集合的单个检查组中*/
                checkGroup.setCheckItems(checkItemList);
            }
            /*将检查组列表信息（此时它里面还包含检查项信息）装入 Setmeal 表中*/
            setmeal.setCheckGroups(checkGroupList);
        }
        return setmeal;
    }

    /*批量查询*/
    @Override
    public Setmeal findByIdBatch(Integer id) {
        /*查询套餐信息*/
//        Setmeal setmeal = setmealDao.querySetmealId(id);
//
//        if (setmeal != null){
//            /*根据套餐id,查询检查组id列表*/
//            List<Integer> checkGroupIds = setmealDao.queryCheckGroupIds(setmeal.getId());
//            /*根据检查组id查询检查组列表*/
//            List<CheckGroup> checkGroupList = setmealDao.queryCheckGroupList(checkGroupIds);
//
//            /*根据检查组id查询检查项列表*/
//            List<CheckItem> checkItemList = setmealDao.queryCheckItemList(checkGroupIds);
//
//            /*构建容器，key为检查组 id，value为此检查组对应的检查项集合*/
//            Map<Integer,List<CheckItem>> collection = new HashMap<>();
//
//            /*遍历检查项列表*/
//            for (CheckItem checkItem : checkItemList) {
//                /*获取检查项所属的检查组id*/
//                Integer checkGroupId = checkItem.getCheckGroupId();
//                /*从容器中取出检查项集合，每个检查组id初次取时肯定为空*/
//                List<CheckItem> checkItems = collection.get(checkGroupId);
//
//                if (checkItems == null){
//                    /*构建检查项集合*/
//                    checkItems = new ArrayList<>();
//                    collection.put(checkGroupId,checkItems);
//                }
//                /*将检查项置入检查组*/
//                checkItems.add(checkItem);
//            }
//
//            /*根据检查组id，将检查项集合取出放入检查组类对象的检查项集合列表中*/
//            for (CheckGroup checkGroup : checkGroupList) {
//                checkGroup.setCheckItems(collection.get(checkGroup.getId()));
//            }
//
//            setmeal.setCheckGroups(checkGroupList);
//
//        }
//
//
//        return setmeal;

        /*
        * 我把查询检查组的代码 原本的代码插入到我的else判断语句中
        * */

        //获取从前端传过来的Id
        String ids = jedisPool.getResource().get(id.toString());
        //判断redis是否存在数据
        if (!StringUtils.isEmpty(ids)) {
            Setmeal setmeal1 = JSON.parseObject(ids, Setmeal.class);
            return setmeal1;
        }else{
            //*获取套餐信息*//*
            Setmeal setmeal = setmealDao.querySetmealId(id);
            //*获取检查组id列表*//*
            List<Integer> checkGroupIds = setmealDao.queryCheckGroupIds(setmeal.getId());
            //* 获取检查组列表*//*
            List<CheckGroup> checkGroupList = setmealDao.queryCheckGroupList(checkGroupIds);

            //* 根据检查组id列表获取所有检查项集合，并将它们对应的检查组id放进这些检查项中*//*
            List<CheckItem> checkItemList = setmealDao.queryCheckItemList(checkGroupIds);

            //*构建容器,此容器的key是检查项集合对应的检查组id,就是把上一步查出来的结果用检查组id区分开来*//*
            Map<Integer, List<CheckItem>> collection = new HashMap<>();

            //*遍历所有检查项*//*
            for (CheckItem checkItem : checkItemList) {
                //* 取出它所属的检查组的id*//*
                Integer checkGroupId = checkItem.getCheckGroupId();

                //* 取出检查项List集合，便于盛装属于某一个检查组的检查项，
//              在特属于每一个检查组id时，此List都为空*//
                List<CheckItem> checkItems = collection.get(checkGroupId);

                //*如果检查项List集合为空，我们就构建它*//*
                if (checkItems == null) {
                    checkItems = new ArrayList<>();
                    //*将新创建好的检查项List集合放入map集合*//*
                    collection.put(checkGroupId, checkItems);
                }
                //*将检查项依次放入我们创建的检查项List集合*//*
                checkItems.add(checkItem);
            }

//*将检查项集合置入检查组集合中*//*

            for (CheckGroup checkGroup : checkGroupList) {
                checkGroup.setCheckItems(collection.get(checkGroup.getId()));
            }
//*将检查组集合置入套餐中*//*
            setmeal.setCheckGroups(checkGroupList);
//            Setmeal byId = setmealDao.querySetmealId(id);
            String setmeal2 = JSON.toJSONString(setmeal);
            jedisPool.getResource().set(id.toString(),setmeal2);
            return setmeal;
        }
//       return setmeal;
    }


    @Override
    public Map<String, Object> querySetmealOrderPercent() {


        //TODO :    data: res.data.data.setmealNames
        // data:res.data.data.setmealCount,

        Map<String, Object> map = new HashMap<>();

        /*套餐名集合*/
        List<String> setmealNames = setmealDao.querySetmealNames();
        /*套餐预约数量与套餐名称*/
        List<NameValueVCS> setmealCount = setmealDao.querySetmealNameAndNumber();


        map.put("setmealNames", setmealNames);
        map.put("setmealCount",setmealCount);
        return map;
    }

    @Override
    public Result getSetmealReport() {
        Map<String, Object> map = new HashMap<>();
        List<String> list = setmealDao.getSetNames();
        List<Map<String, Object>> mapList = new ArrayList<>();
        map.put("setmealNames", list);
        for (String setname : list) {
            Map<String, Object> map1 = new HashMap<>();
            int count = setmealDao.getsetCountBySetName(setname);
            map1.put("name", setname);
            map1.put("value", count);
            mapList.add(map1);
        }
        map.put("setmealCount", mapList);
        return Result.success("",map);
    }
}
